package com.he.controller;

import com.he.annotation.AccessLimit;
import com.he.annotation.OperationLogger;
import com.he.domain.Result;
import com.he.domain.dto.*;
import com.he.domain.vo.*;
import com.he.enums.LikeTypeEnum;
import com.he.service.ArticleService;
import com.he.strategy.context.LikeStrategyContext;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;

/**
 * @author He
 * @version 1.0
 * @Date 2023/9/17 21:21
 * @Desc 文章控制器
 */
@Tag(name = "文章模块")
@RestController
@Validated
public class ArticleController {

    @Resource
    private ArticleService articleService;

    @Resource
    private LikeStrategyContext likeStrategyContext;

    @Operation(description = "查看文章归档")
    @AccessLimit(seconds = 1, maxCount = 5)
    @GetMapping("/archives/list")
    public Result<PageResult<ArchiveVO>> getArchiveList(){
        return Result.success(articleService.getArchiveListVO());
    }

    /**
     * 查看首页文章列表
     *
     * @return {@link Result< ArticleHomeVO >}
     */
    @Operation(description = "查看首页文章列表")
    @AccessLimit(seconds = 1, maxCount = 5)
    @GetMapping("/article/list")
    public Result<PageResult<ArticleHomeVO>> listArticleHomeVO() {
        return Result.success(articleService.listArticleHomeVO());
    }

    @Operation(description = "获取热门文章列表")
    @AccessLimit(seconds = 1, maxCount = 5)
    @GetMapping("/article/hot")
    public Result<?> getHotArticleList(){
        return Result.success(articleService.getHotArticleList());
    }

    @Operation(description = "文章贡献统计")
    @AccessLimit(seconds = 1, maxCount = 5)
    @GetMapping("/article/countDate")
    public Result<?> getArticleCountAndDate(@RequestParam(name = "year")@Min(value = 2023, message = "年份必须大于2023")
                                                @Max(value = 2100, message = "年份必须小于2100") Integer year){
        return Result.success(articleService.getArticleCountAndDate(year));
    }

    /**
     * 上传文章图片
     *
     * @param file 文件
     * @return {@link Result<String>} 文章图片地址
     */
    @Operation(description = "上传文章图片")
    @PreAuthorize("@ps.hasPermission('blog:article:upload')")
    @PostMapping("/admin/article/upload")
    public Result<String> saveArticleImages(@RequestParam(value = "file") MultipartFile file) {
        return Result.success(articleService.saveArticleImages(file));
    }

    /**
     * 添加文章
     *
     * @param article 文章信息
     * @return {@link Result<>}
     */
    @Operation(description = "添加文章")
    @PreAuthorize("@ps.hasPermission('blog:article:add')")
    @PostMapping("/admin/article/add")
    public Result<?> addArticle(@Validated @RequestBody ArticleDTO article) {
        articleService.addArticle(article);
        return Result.success();
    }

    /**
     * 查看后台文章列表
     *
     * @param condition 条件
     * @return {@link Result<ArticleBackVO>} 后台文章列表
     */
    @Operation(description = "查看后台文章列表")
    @PreAuthorize("@ps.hasPermission('blog:article:list')")
    @GetMapping("/admin/article/list")
    public Result<PageResult<ArticleBackVO>> listArticleBackVO(ConditionDTO condition) {
        return Result.success(articleService.listArticleBackVO(condition));
    }

    /**
     * 置顶文章
     *
     * @param top 置顶信息
     * @return {@link Result<>}
     */
    @Operation(description = "置顶文章")
    @PreAuthorize("@ps.hasPermission('blog:article:top')")
    @PutMapping("/admin/article/top")
    public Result<?> updateArticleTop(@Validated @RequestBody TopDTO top) {
        articleService.updateArticleTop(top);
        return Result.success();
    }


    /**
     * 推荐文章
     *
     * @param recommend 推荐信息
     * @return {@link Result<>}
     */
    @Operation(description = "推荐文章")
    @PreAuthorize("@ps.hasPermission('blog:article:recommend')")
    @PutMapping("/admin/article/recommend")
    public Result<?> updateArticleRecommend(@Validated @RequestBody RecommendDTO recommend) {
        articleService.updateArticleRecommend(recommend);
        return Result.success();
    }

    /**
     * 删除文章
     *
     * @param articleIdList 文章id集合
     * @return {@link Result<>}
     */
    @Operation(description = "删除文章")
    @PreAuthorize("@ps.hasPermission('blog:article:delete')")
    @DeleteMapping("/admin/article/delete")
    public Result<?> deleteArticle(@RequestBody List<Integer> articleIdList) {
        articleService.deleteArticle(articleIdList);
        return Result.success();
    }

    /**
     * 回收或恢复文章
     * @param delete 逻辑删除
     * @return {@link Result<>}
     */
    @Operation(description = "回收或恢复文章")
    @PreAuthorize("@ps.hasPermission('blog:article:recycle')")
    @PutMapping("/admin/article/recycle")
    public Result<?> updateArticleDelete(@Validated @RequestBody DeleteDTO delete) {
        articleService.updateArticleDelete(delete);
        return Result.success();
    }

    /**
     * 获取编辑文章信息
     *
     * @param articleId 文章id
     * @return {@link Result<ArticleInfoVO>} 后台文章
     */
    @Operation(description = "编辑文章")
    @PreAuthorize("@ps.hasPermission('blog:article:edit')")
    @GetMapping("/admin/article/edit/{articleId}")
    public Result<ArticleInfoVO> editArticle(@PathVariable("articleId") Integer articleId) {
        return Result.success(articleService.editArticle(articleId));
    }

    /**
     * 修改文章
     *
     * @param article 文章信息
     * @return {@link Result<>}
     */
    @Operation(description = "修改文章")
    @PreAuthorize("@ps.hasPermission('blog:article:update')")
    @PutMapping("/admin/article/update")
    public Result<?> updateArticle(@Validated @RequestBody ArticleDTO article) {
        articleService.updateArticle(article);
        return Result.success();
    }

    /**
     * 点赞文章
     *
     * @param articleId 文章id
     * @return {@link Result<>}
     */
    @Operation(description = "点赞文章")
    @AccessLimit(seconds = 60, maxCount = 3)
    @PreAuthorize("@ps.hasPermission('blog:article:like')")
    @PostMapping("/article/{articleId}/like")
    public Result<?> likeArticle(@PathVariable("articleId") Integer articleId) {
        likeStrategyContext.executeLikeStrategy(LikeTypeEnum.ARTICLE, articleId);
        return Result.success();
    }


    /**
     * 搜索文章
     *
     * @param keyword 关键字
     * @return {@link Result<ArticleSearchVO>} 文章列表
     */
    @Operation(description = "搜索文章")
    @GetMapping("/article/search")
    public Result<List<ArticleSearchVO>> listArticlesBySearch(String keyword) {
        return Result.success(articleService.listArticlesBySearch(keyword));
    }

    /**
     * 查看文章
     *
     * @param articleId 文章id
     * @return {@link Result<ArticleVO>} 首页文章
     */
    @AccessLimit(seconds = 1, maxCount = 1)
    @Operation(description = "查看文章")
    @GetMapping("/article/{articleId}")
    public Result<ArticleVO> getArticleHomeById(@PathVariable("articleId") Integer articleId) {
        return Result.success(articleService.getArticleHomeById(articleId));
    }

}
